﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Vision001.Helper;
using Vision001.Models;
using Vision001.ViewModels;

namespace Vision001.Procedure
{
    public class SocketServer
    {
        private bool ResStatus = false;
        public static updateHandler updatemessage;
        private readonly TcpListener _listener;
        private TcpClient _client;
        private bool _isRunning;
        private CancellationTokenSource _cts;
        public double Timeout = 1000;

        public SocketServer(int port)
        {
            _listener = new TcpListener(IPAddress.Any, port);
        }

        public async Task StartAsync()
        {
            _cts = new CancellationTokenSource();
            _isRunning = true;

            _listener.Start();
            UpdateMessage("服务器已启动，等待连接...");

            while (_isRunning && !_cts.IsCancellationRequested)
            {
                try
                {
                    UpdateMessage("等待客户端连接！");
                    _client = await _listener.AcceptTcpClientAsync();
                    UpdateMessage("客户端已连接！");

                    // 启动接收任务
                    await Task.Run(() => ReceiveMessagesAsync(_cts.Token), _cts.Token);
                }
                catch (OperationCanceledException)
                {
                    UpdateMessage("服务器已停止", LogLevel.Error);
                }
                catch (Exception ex)
                {
                    UpdateMessage($"连接错误: {ex.Message}", LogLevel.Error);
                    await Task.Delay(3000); // 3秒后重试
                }
            }
        }

        private async Task ReceiveMessagesAsync(CancellationToken ct)
        {
            var buffer = new byte[1024];
            var stream = _client.GetStream();

            while (_client.Connected && !ct.IsCancellationRequested)
            {
                try
                {
                    using (var timeoutCt = new CancellationTokenSource(TimeSpan.FromSeconds(Timeout)))
                    using (var linkedCt = CancellationTokenSource.CreateLinkedTokenSource(ct, timeoutCt.Token))
                    {
                        int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, linkedCt.Token);
                        if (bytesRead == 0) break;

                        string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);

                        // UpdateMessage($"收到消息: {message}");
                        await Send(message);

                        ResStatus = true;
                    }
                }
                catch (OperationCanceledException) when (!ct.IsCancellationRequested)
                {
                    UpdateMessage("接收超时，客户端可能无响应", LogLevel.Error);
                    break;
                }
                catch (Exception ex)
                {
                    //UpdateMessage($"接收错误: {ex.Message}", LogLevel.Error);
                    break;
                }
            }
            UpdateMessage($"客户端已断开", LogLevel.Error);
            _client?.Close();
        }

        private string Message = "";
        private int TimeOut = 60000;

        public async Task<string> ReceiveRes()
        {
            try
            {
                if (_client == null) { return "1"; }
                string result = "";
                Stopwatch stopwatch = Stopwatch.StartNew();
                while (true)
                {
                    if (ResStatus)
                    {
                        result = Message;
                        Message = "";
                        break;
                    }
                    if (stopwatch.ElapsedMilliseconds > TimeOut)
                    {
                        break;
                    }
                    await Task.Delay(10);
                }
                ResStatus = false;
                return result;
            }
            catch (Exception e)
            {
                UpdateMessage(e.Message, LogLevel.Error);
                return "1";
            }
        }

        private void UpdateMessage(string msg, LogLevel logLevel = LogLevel.Info)
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                updatemessage?.Invoke(msg, logLevel);
            }));
        }

        /// <summary>
        /// 关闭通讯
        /// </summary>
        public void Close()
        {
            _client?.Close();
            _cts?.Cancel();
        }

        /// <summary>
        /// 当握手失败的时候，跳出循环继续等待
        /// </summary>
        public void JumpWhlie()
        {
            _client?.Close();
        }

        /// <summary>
        /// 根据接受到的信息反馈
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public async Task Send(string msg)
        {
            try
            {
                Message = "";
                string info = "";
                switch (msg)
                {
                    case "need":
                        info = Global.RobotStatus;
                        await SendMessagesAsync(info);
                        break;

                    case "code":
                        info = Global.RobotCode;
                        await SendMessagesAsync(info);
                        break;

                    case "join":

                        Global.TestRobotIsOK = true;
                        break;

                    case "1":

                        await SendMessagesAsync("1");
                        break;

                    default:
                        break;
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 发送信息
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public async Task SendMessagesAsync(string msg)
        {
            if (_client == null) { return; }

            Message = "";
            var stream = _client.GetStream();

            if (_client.Connected)
            {
                try
                {
                    string input = msg;
                    byte[] data = Encoding.UTF8.GetBytes(input);
                    await stream.WriteAsync(data, 0, data.Length);
                }
                catch (Exception ex)
                {
                    UpdateMessage($"发送错误: {ex.Message}", LogLevel.Error);
                }
            }
        }
    }
}